﻿using System;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using RikMigrations.Providers;

namespace RikMigrations.MsBuildTask
{
    public class Migrate : Task
    {
        private int? version;
        private string module = MigrationManager.DefaultModuleName;
        private string assembly;
        private string catalog;
        private string server;
        private string username;
        private string password;
        private string _connectionString;


        public int? Version
        {
            get { return version; }
            set { version = value; }
        }

        public string Module
        {
            get { return module; }
            set { module = value; }
        }

        [Required]
        public string AssemblyName
        {
            get { return assembly; }
            set { assembly = value; }
        }

        public string Catalog
        {
            get { return catalog; }
            set { catalog = value; }
        }

        public string Server
        {
            get { return server; }
            set { server = value; }
        }

        public string Username
        {
            get { return username; }
            set { username = value; }
        }

        public string Password
        {
            get { return password; }
            set { password = value; }
        }

        public string ConnectionString
        {
            get { return _connectionString; }
            set { _connectionString = value; }
        }


        private static IBuildEngine Engine { get; set; } 


        public override bool Execute()
        {
            Engine = BuildEngine;

            LogWriter writer = new LogWriter();
            Console.SetOut(writer);

            if (_connectionString == String.Empty)
            {
                if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password))
                {
                    DbProvider.DefaultConnectionString =
                        string.Format("data source={0};initial catalog={1};user id={2};password={3}", server,
                                      catalog, username, password);
                }
                else
                {
                    DbProvider.DefaultConnectionString =
                        string.Format("data source={0};initial catalog={1};Integrated Security=SSPI;", server,
                                      catalog);
                }
            }

            DbProvider.DefaultConnectionString = _connectionString;


            if (version == null)
            {
                Console.WriteLine("Updgrading Maximum");
                MigrationManager.UpgradeMax(Assembly.LoadFrom(AssemblyName),
                                                    new MssqlProvider(), new string[] { module });
            }
            else
            {
                Console.WriteLine("Updgrading To Version");
                MigrationManager.MigrateTo(Assembly.LoadFrom(AssemblyName),
                                                   module,
                                                   Version.Value);
            }

            return true;
        }



        public class LogWriter : TextWriter
        {
            public override Encoding Encoding
            {
                get { return Encoding.ASCII; }
            }

            public override void Write(string value)
            {
                log(value);
            }

            public override void WriteLine(string value)
            {
                log(value);
            }

            public override void  Write(string format, object arg0)
            {
                log(String.Format(format, arg0));
            }

            private void log(string message)
            {
                BuildMessageEventArgs args = new BuildMessageEventArgs(message, string.Empty, "Migrate", MessageImportance.Normal);
                Engine.LogMessageEvent(args);
            }
        }
    }

}